package com.exam.api.modules.goods.utils.xhs;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.exam.api.common.utils.RedisClient;
import com.xiaohongshu.fls.opensdk.client.DataClient;
import com.xiaohongshu.fls.opensdk.client.OauthClient;
import com.xiaohongshu.fls.opensdk.client.OrderClient;
import com.xiaohongshu.fls.opensdk.client.ProductClient;
import com.xiaohongshu.fls.opensdk.entity.BaseResponse;
import com.xiaohongshu.fls.opensdk.entity.data.request.BatchDecryptRequest;
import com.xiaohongshu.fls.opensdk.entity.data.response.BatchDecryptResponse;
import com.xiaohongshu.fls.opensdk.entity.oauth.request.GetAccessTokenRequest;
import com.xiaohongshu.fls.opensdk.entity.oauth.request.RefreshTokenRequest;
import com.xiaohongshu.fls.opensdk.entity.oauth.response.GetAccessTokenResponse;
import com.xiaohongshu.fls.opensdk.entity.oauth.response.RefreshTokenResponse;
import com.xiaohongshu.fls.opensdk.entity.order.Requset.GetOrderDetailRequest;
import com.xiaohongshu.fls.opensdk.entity.order.Requset.GetOrderListRequest;
import com.xiaohongshu.fls.opensdk.entity.order.Requset.GetOrderReceiverInfoRequest;
import com.xiaohongshu.fls.opensdk.entity.order.Response.*;
import com.xiaohongshu.fls.opensdk.entity.product.request.v3.SearchItemListRequest;
import com.xiaohongshu.fls.opensdk.entity.product.response.v3.ItemDetail;
import com.xiaohongshu.fls.opensdk.entity.product.response.v3.SearchItemListResponse;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Component
@Log4j2
public class XhsRequest {
    @Resource
    private RedisClient redisClient;

    private static final String APP_ID = "a8fa3aa8fa5644278a32";
    private static final String APP_SECRET = "d148274e904bd8433f0b68632973fc16";
    private static final String VERSION = "2.0";
    private static final String URL = "https://ark.xiaohongshu.com/ark/open_api/v3/common_controller";
    private static final String MERCHANT_CODE = "code-845409dca2d042afb44e9b3596e1e3f5-f8678dcedce147f49bbd0ba70beaba93";


    public BatchDecryptResponse batchDecrypt(GetOrderDetailResponse orderDetail,OrderReceiverInfo receiver) throws IOException {

        BatchDecryptRequest.baseInfo baseInfo = new BatchDecryptRequest.baseInfo();
        baseInfo.setDataTag(orderDetail.getOrderId());
        baseInfo.setEncryptedData(receiver.getReceiverPhone());
        DataClient client = new DataClient(URL,APP_ID,VERSION,APP_SECRET);
        BatchDecryptRequest request = new BatchDecryptRequest();
        request.setActionType("1");
        request.setAppUserId("1");
        request.setBaseInfos(Collections.singletonList(baseInfo));
        BaseResponse<BatchDecryptResponse> execute = client.execute(request, getAccessToken());
        BatchDecryptResponse data = execute.getData();
        log.info("解密手机号:{}", JSONUtil.toJsonStr( data));
        return data;
    }

    public OrderReceiverInfo getOrderReceiverInfo( GetOrderDetailResponse orderDetail) throws IOException {

        GetOrderReceiverInfoRequest.OrderReceiverQuery receiverQuery = new GetOrderReceiverInfoRequest.OrderReceiverQuery();
        receiverQuery.setOrderId(orderDetail.getOrderId());
        receiverQuery.setOpenAddressId(orderDetail.getOpenAddressId());

        OrderClient client = new OrderClient(URL,APP_ID,VERSION,APP_SECRET);
        GetOrderReceiverInfoRequest request = new GetOrderReceiverInfoRequest();
        request.setIsReturn(false);
        request.setReceiverQueries(Collections.singletonList(receiverQuery));
        GetOrderReceiverInfoResponse data = client.execute(request, getAccessToken()).getData();
        log.info(JSONUtil.toJsonStr( data));
        return data.getReceiverInfos().get(0);
    }

    public GetOrderDetailResponse getOrderInfo(String orderId) throws IOException {
        OrderClient client = new OrderClient(URL,APP_ID,VERSION,APP_SECRET);
        GetOrderDetailRequest request = new GetOrderDetailRequest();
        request.setOrderId(orderId);
        GetOrderDetailResponse data = client.execute(request, getAccessToken()).getData();
        log.info("订单详情:{}", JSONUtil.toJsonStr( data));
        return data;
    }
    public List<OrderSimpleDetail> getOrderList() throws IOException {
        Long end = System.currentTimeMillis();
        Long start = System.currentTimeMillis() - 86400000;

        OrderClient client = new OrderClient(URL,APP_ID,VERSION,APP_SECRET);
        GetOrderListRequest request = new GetOrderListRequest();
        request.setPageNo(1);
        request.setPageSize(10);
        request.setStartTime(start);
        request.setEndTime(end);
        request.setTimeType(1);
        request.setOrderStatus(4);
        GetOrderListResponse data = client.execute(request, getAccessToken()).getData();

        data.getOrderList().forEach(item -> {
            log.info(JSONUtil.toJsonStr(item));
        });
        if(data.getTotal() == 0){
            log.warn("没有订单");
        }
        return data.getOrderList();
    }

    public List<ItemDetail> getProductList() throws IOException {
        List<ItemDetail> list = new ArrayList<>();
        Integer pageNo = 1;
        while (true){
            ProductClient productClient = new ProductClient(URL,APP_ID,VERSION,APP_SECRET);
            SearchItemListRequest request = new SearchItemListRequest();
            request.setPageNo(pageNo);
            request.setPageSize(999);
            SearchItemListRequest.ItemSearchParam searchParam = new SearchItemListRequest.ItemSearchParam();
            searchParam.setBuyable(true);
            request.setSearchParam(searchParam);
            SearchItemListResponse data = productClient.execute(request, getAccessToken()).getData();
            log.info(data);
            list.addAll(data.getItemDetailV3s());
            if(list.size() >= data.total){
                break;
            }
            pageNo ++;
        }
        return list;
    }
    public GetAccessTokenResponse getAccessTokenResponse() throws IOException {
        OauthClient oauthClient = new OauthClient(URL,APP_ID,VERSION,APP_SECRET);
        GetAccessTokenRequest request = new GetAccessTokenRequest();
        request.setCode(MERCHANT_CODE);
        BaseResponse<GetAccessTokenResponse> execute = oauthClient.execute(request);
        log.info(execute);
        if(Objects.equals(execute.getCode(), "999")){
            log.error("获取token失败,去更新Code[https://open.xiaohongshu.com/application/detail?appId=a8fa3aa8fa5644278a32&status=9]");
        }
        return execute.getData();
    }


    public String getAccessToken(){
        String tokenKey = "XHS:ACCESS:TOKEN";
        String refreshTokenKey = "XHS:ACCESS:REFRESH_TOKEN";
        String token = (String) redisClient.get(tokenKey);
        String refreshToken = (String) redisClient.get(refreshTokenKey);

        long ttl = redisClient.ttl(tokenKey);

        try{
            if(StrUtil.isBlank(refreshToken)){
                GetAccessTokenResponse accessTokenResponse = getAccessTokenResponse();
                token = accessTokenResponse.getAccessToken();
                refreshToken = accessTokenResponse.getRefreshToken();

                long accessTokenExpiresAt = accessTokenResponse.getAccessTokenExpiresAt();
                long refreshTokenExpiresAt = accessTokenResponse.getRefreshTokenExpiresAt();
                redisClient.set(tokenKey,token);
                redisClient.set(refreshTokenKey,refreshToken);

                redisClient.expire(tokenKey, (accessTokenExpiresAt - System.currentTimeMillis()) / 1000);
                redisClient.expire(refreshTokenKey, (refreshTokenExpiresAt - System.currentTimeMillis()) / 1000);
                log.info("生成了token:{} 过期时间：{}",token,accessTokenExpiresAt);
            }else if(ttl <= 86400 * 4) {
                //刷新一下token
                OauthClient oauthClient = new OauthClient(URL,APP_ID,VERSION,APP_SECRET);
                RefreshTokenRequest request = new RefreshTokenRequest();
                request.setRefreshToken(refreshToken);
                BaseResponse<RefreshTokenResponse> execute = oauthClient.execute(request);
                RefreshTokenResponse refreshTokenResponse = execute.getData();
                if(Objects.nonNull(refreshTokenResponse)){
                    token = refreshTokenResponse.getAccessToken();
                    refreshToken = refreshTokenResponse.getRefreshToken();
                    long accessTokenExpiresAt = refreshTokenResponse.getAccessTokenExpiresAt();
                    long refreshTokenExpiresAt = refreshTokenResponse.getRefreshTokenExpiresAt();
                    redisClient.set(tokenKey,token);
                    redisClient.set(refreshTokenKey,refreshToken);

                    redisClient.expire(tokenKey, (accessTokenExpiresAt - System.currentTimeMillis()) / 1000);
                    redisClient.expire(refreshTokenKey, (refreshTokenExpiresAt - System.currentTimeMillis()) / 1000);
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return token;
    }
}
